package Day_0202.Spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

/**
 * @author zxc
 * @date 2023/02/02 16:20
 **/
public class Autowired_Resource {
    public static void main(String[] args) {
        /**
         * @Autowired和@Resource注解的区别
         * ===》
         * @Resource和@Autowired都是做bean的注入时使用的，
         * 其实@Resource并不是Spring的注解，它的包是javax.annotation.Resource，需要导入，
         * 但是Spring支持该注解的注入。
         *
         * 1、共同点
         * 两者都可以写在字段和setter方法上。两者如果都写在字段上，那么就不需要再写setter方法。
         *
         * 2、不同点
         * （1）@Autowired
         *  a.@Autowired为Spring提供的注解，需要导入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。
         *
         *  b.@Autowired注解是按照类型（byType）装配依赖对象，
         *  默认情况下它要求依赖对象必须存在，如果允许null值，可以设置它的required属性为false。
         *  如果我们想使用按照名称（byName）来装配，可以结合@Qualifier注解一起使用。
         *  ===》
         *  总结 ：
         *  （1）一般来说，@Autowired注解是按照类型（ByType）装配依赖对象的;
         *  （注意 ：@Autowired注解要求依赖对象必须存在;）
         *  （2）结合@Qualifier注解使用的话，可以按照名称（ByName）装配依赖对象;
         *
         *
         * （2）@Resource
         *  a.@Resource默认按照ByName自动注入，由J2EE提供，需要导入包javax.annotation.Resource。
         *
         *  b.@Resource有两个重要的属性：name和type，而Spring将@Resource注解的name属性解析为bean的名字，而type属性则解析为bean的类型。
         *  所以，如果使用name属性，则使用byName的自动注入策略，而使用type属性时则使用byType自动注入策略。
         *  如果既不制定name也不制定type属性，这时将通过反射机制使用byName自动注入策略。
         *  注：最好是将@Resource放在setter方法上，因为这样更符合面向对象的思想，通过set、get去操作属性，而不是直接去操作属性。
         *  ===》
         *  总结 ：
         *  （1）@Resource注解包含name && type属性;
         *  （2）name属性，代表了bean的名称;同时，type属性，则是代表了bean的类型;
         *  （3）@Resource注解默认使用ByName来进行对象的依赖注入;
         *
         * @Resource装配顺序：
         * ①如果同时指定了name和type，则从Spring上下文中找到唯一匹配的bean进行装配，找不到则抛出异常。
         *
         * ②如果指定了name，则从上下文中查找名称（id）匹配的bean进行装配，找不到则抛出异常。
         *
         * ③如果指定了type，则从上下文中找到类似匹配的唯一bean进行装配，找不到或是找到多个，都会抛出异常。
         *
         * ④如果既没有指定name，又没有指定type，则自动按照byName方式进行装配；
         * 如果没有匹配到bean，则回退为一个原始类型进行匹配，如果匹配则自动装配。
         *
         *
         * 总结 ：
         * ===》
         * @Resource的作用相当于@Autowired，只不过@Autowired按照byType自动注入
         * （即，@Autowired注解是属于@Resource注解的，即@Autowored只能够按照类型进行依赖注入ByType）
         */
    }
    // @Autowired注解可以用于字段和setter方法上;
//    public class TestServiceImpl {
//        // @Autowired注解是按照类型（ByType）装配依赖对象;
//        @Autowired
//        // 配合@Qualifier注解使用的话，即可以实现按照名字（ByName）装配依赖对象;
//        @Qualifier("userDao")
//        private UserDao userDao; // 用于字段上
//
//        @Autowired
//        public void setUserDao(UserDao userDao) { // 用于属性的方法上
//            this.userDao = userDao;
//        }
//    }
}
